home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / machserver / 1.098 / sig / sigStubs.c < prev    next >
C/C++ Source or Header  |  1991-08-09  |  13KB  |  484 lines

  1. /* 
  2.  * sigStubs.c --
  3.  *
  4.  *    Stubs for Unix compatible system calls.
  5.  *
  6.  * Copyright 1990 Regents of the University of California
  7.  * Permission to use, copy, modify, and distribute this
  8.  * software and its documentation for any purpose and without
  9.  * fee is hereby granted, provided that the above copyright
  10.  * notice appear in all copies.  The University of California
  11.  * makes no representations about the suitability of this
  12.  * software for any purpose.  It is provided "as is" without
  13.  * express or implied warranty.
  14.  */
  15.  
  16. #ifndef lint
  17. static char rcsid[] = "$Header: /sprite/src/kernel/sig/RCS/sigStubs.c,v 1.6 91/08/09 14:55:08 shirriff Exp $";
  18. #endif /* not lint */
  19.  
  20. #define MACH_UNIX_COMPAT
  21.  
  22. #include <sprite.h>
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <status.h>
  26. #include <errno.h>
  27. #include <user/sys/types.h>
  28. #include <user/sys/wait.h>
  29. #include <user/sys/time.h>
  30. #include <user/sys/resource.h>
  31. #include <user/sys/signal.h>
  32. #include <mach.h>
  33. #include <proc.h>
  34. #include <procUnixStubs.h>
  35. #include <vm.h>
  36. #include <fsutil.h>
  37. #include <assert.h>
  38. #include <sig.h>
  39. #include <sigInt.h>
  40. #include <compatInt.h>
  41.  
  42. extern unsigned int     sigBitMasks[SIG_NUM_SIGNALS];
  43. extern int        sigDefActions[SIG_NUM_SIGNALS];
  44. extern int        sigCanHoldMask;
  45.  
  46. int debugSigStubs;
  47.  
  48.  
  49. /*
  50.  *----------------------------------------------------------------------
  51.  *
  52.  * Sig_KillStub --
  53.  *
  54.  *    Procedure to map from Unix kill system call to Sprite.
  55.  *
  56.  * Results:
  57.  *    Error code is returned upon error.  Otherwise SUCCESS is returned.
  58.  *
  59.  * Side effects:
  60.  *    Side effects associated with the system call.
  61.  *
  62.  *----------------------------------------------------------------------
  63.  */
  64. int
  65. Sig_KillStub(pid, sig)
  66.     int pid;
  67.     int sig;
  68. {
  69.     ReturnStatus status;
  70.     int         spriteSignal;
  71.  
  72.     if (debugSigStubs) {
  73.     printf("Sig_KillStub(0x%x, 0x%x)\n", pid, sig);
  74.     }
  75.     status = Compat_UnixSignalToSprite(sig, &spriteSignal);
  76.     if (status == FAILURE || (spriteSignal == NULL && sig != 0)) {
  77.     status = SYS_INVALID_ARG;
  78.     } else {
  79.     if (pid == 0) {
  80.         pid = PROC_MY_PID;
  81.     }
  82.     status = Sig_UserSend(spriteSignal, pid, FALSE);
  83.     }
  84.     if (status != SUCCESS) {
  85.     Mach_SetErrno(Compat_MapCode(status));
  86.     return -1;
  87.     }
  88.     return 0;
  89. }
  90.  
  91.  
  92.  
  93. /*
  94.  *----------------------------------------------------------------------
  95.  *
  96.  * Sig_KillpgStub --
  97.  *
  98.  *    Procedure to map from Unix killpg system call to Sprite.
  99.  *
  100.  * Results:
  101.  *    Error code is returned upon error.  Otherwise SUCCESS is returned.
  102.  *
  103.  * Side effects:
  104.  *    Side effects associated with the system call.
  105.  *
  106.  *----------------------------------------------------------------------
  107.  */
  108. int
  109. Sig_KillpgStub(pgrp, sig)
  110.     int pgrp;
  111.     int sig;
  112. {
  113.     ReturnStatus status;
  114.     int         spriteSignal;
  115.  
  116.     if (debugSigStubs) {
  117.     printf("Sig_KillpgStub(0x%x, 0x%x)\n", pgrp, sig);
  118.     }
  119.     status = Compat_UnixSignalToSprite(sig, &spriteSignal);
  120.     if (status == FAILURE || (spriteSignal == NULL && sig != 0)) {
  121.     Mach_SetErrno(EINVAL);
  122.     return -1;
  123.     }
  124.     status = Sig_UserSend(spriteSignal, pgrp, TRUE);
  125.     if (status != SUCCESS) {
  126.     Mach_SetErrno(Compat_MapCode(status));
  127.     return -1;
  128.     }
  129.     return 0;
  130. }
  131.  
  132.  
  133.  
  134. /*
  135.  *----------------------------------------------------------------------
  136.  *
  137.  * Sig_SigvecStub --
  138.  *
  139.  *    Procedure to map from Unix sigvec system call to Sprite Sig_SetAction.
  140.  *
  141.  * Results:
  142.  *    Error code is returned upon error.  Otherwise SUCCESS is returned.
  143.  *
  144.  * Side effects:
  145.  *    The signal handler associated with the specified signal is modified.
  146.  *
  147.  *----------------------------------------------------------------------
  148.  */
  149. int
  150. Sig_SigvecStub(sig, newVectorPtr, oldVectorPtr)
  151.     int         sig;        /* Signal to set the vector for. */
  152.     struct sigvec    *newVectorPtr;    /* New vector. */
  153.     struct sigvec    *oldVectorPtr;    /* Old vector. */
  154. {
  155.     int         spriteSignal;    /* Equivalent signal for Sprite */
  156.     Sig_Action         newAction;    /* Action to take */
  157.     Sig_Action         oldAction;    /* Former action */
  158.     ReturnStatus     status;        /* Generic result code */
  159.     struct sigvec newVector;
  160.     struct sigvec oldVector;
  161.     Proc_ControlBlock    *procPtr = Proc_GetActualProc();
  162.     Address        dummy;
  163.  
  164.     if (debugSigStubs) {
  165.     printf("Sig_SigvecStub(%d, %x, %x)\n", sig, newVectorPtr,
  166.         oldVectorPtr);
  167.     }
  168.  
  169.     /*
  170.      * Set magic flag to indicate we're in Unix signal mode.
  171.      */
  172.     procPtr->unixProgress = PROC_PROGRESS_UNIX;
  173.  
  174.     status = Compat_UnixSignalToSprite(sig, &spriteSignal);
  175.     if (status == FAILURE || spriteSignal == NULL) {
  176.     Mach_SetErrno(EINVAL);
  177.     return -1;
  178.     }
  179.     if (newVectorPtr != (struct sigvec *)NULL) {
  180.     status = Vm_CopyIn(sizeof(struct sigvec), (Address)newVectorPtr,
  181.                (Address)&newVector);
  182.     if (status != SUCCESS) {
  183.         Mach_SetErrno(Compat_MapCode(status));
  184.         return -1;
  185.     }
  186.     switch ((int)newVector.sv_handler) {
  187.         case SIG_DFL:
  188.         newAction.action = SIG_DEFAULT_ACTION;
  189.         break;
  190.         case SIG_IGN:
  191.         newAction.action = SIG_IGNORE_ACTION;
  192.         break;
  193.         default:
  194.         newAction.action = SIG_HANDLE_ACTION;
  195.         newAction.handler = (int (*)())newVector.sv_handler;
  196.     }
  197.     status = Compat_UnixSigMaskToSprite(newVector.sv_mask,
  198.                         &newAction.sigHoldMask);
  199.     if (status == FAILURE) {
  200.         printf("Sig_SigvecStub: compat failure\n");
  201.         Mach_SetErrno(EINVAL);
  202.         return -1;
  203.     }
  204.     /*
  205.      * Make sure that the signal is in range.
  206.      */
  207.     if (spriteSignal < SIG_MIN_SIGNAL || spriteSignal >= SIG_NUM_SIGNALS || 
  208.     spriteSignal == SIG_KILL || spriteSignal == SIG_SUSPEND) {
  209.         printf("Sig_SigvecStub: bad signal %d\n", spriteSignal);
  210.         Mach_SetErrno(EINVAL);
  211.         return -1;
  212.     }
  213.     /* 
  214.          * There are two cases:
  215.          *
  216.      *    1) The current action really contains a handler to call.  Thus
  217.      *    the current action is SIG_HANDLE_ACTION.
  218.      *    2) The current action is one of the other four actions.
  219.      */
  220.     if (procPtr->sigActions[spriteSignal] > SIG_NUM_ACTIONS) {
  221.         oldAction.action = SIG_HANDLE_ACTION;
  222.         oldAction.handler = (int (*)())procPtr->sigActions[spriteSignal];
  223.         oldAction.sigHoldMask = procPtr->sigMasks[spriteSignal];
  224.     } else {
  225.         if (procPtr->sigActions[spriteSignal]
  226.             == sigDefActions[spriteSignal]) {
  227.         oldAction.action = SIG_DEFAULT_ACTION;
  228.         } else {
  229.         oldAction.action = procPtr->sigActions[spriteSignal];
  230.         }
  231.     }
  232.  
  233.     /*
  234.      * Make sure that the action is valid.
  235.      */
  236.  
  237.     if (newAction.action < 0 || newAction.action > SIG_NUM_ACTIONS) {
  238.       printf("Sig_SigvecStub: invalid action %d\n", newAction.action);
  239.       Mach_SetErrno(EINVAL);
  240.       return -1;
  241.     }
  242.  
  243.     if (newAction.action == SIG_DEFAULT_ACTION) {
  244.         newAction.action = sigDefActions[spriteSignal];
  245.     }
  246.  
  247.       /*
  248.        * Store the action.  If it is SIG_HANDLE_ACTION then the handler
  249.        * is stored in place of the action.
  250.        */
  251.       if (newAction.action == SIG_HANDLE_ACTION) {
  252.       if (Vm_CopyIn(4, (Address) ((unsigned int) (newAction.handler)), 
  253.           (Address) &dummy) != SUCCESS) {
  254.           Mach_SetErrno(EFAULT);
  255.           return -1;
  256.       }
  257.       procPtr->sigMasks[spriteSignal] =  (sigBitMasks[spriteSignal]
  258.           | newAction.sigHoldMask) & sigCanHoldMask;
  259.       procPtr->sigActions[spriteSignal] = (unsigned int) newAction.handler;
  260.       } else if (newAction.action == SIG_IGNORE_ACTION) {
  261.  
  262.       /*
  263.        * Only actions that can be blocked can be ignored.  This prevents a
  264.        * user from ignoring a signal such as a bus error which would cause
  265.        * the process to take a bus error repeatedly.
  266.        */
  267.       if (sigBitMasks[spriteSignal] & sigCanHoldMask) {
  268.           procPtr->sigActions[spriteSignal] = SIG_IGNORE_ACTION;
  269.           SigClearPendingMask(procPtr, spriteSignal);
  270.       } else {
  271.           Mach_SetErrno(EINVAL);
  272.           return -1;
  273.       }
  274.       procPtr->sigMasks[spriteSignal] = 0;
  275.       } else {
  276.       procPtr->sigActions[spriteSignal] = newAction.action;
  277.       procPtr->sigMasks[spriteSignal] = 0;
  278.       }
  279.     }
  280.     if (oldVectorPtr != NULL) {
  281.     switch (oldAction.action) {
  282.  
  283.       case SIG_DEFAULT_ACTION:
  284.           oldVector.sv_handler = SIG_DFL;
  285.           break;
  286.  
  287.       case SIG_IGNORE_ACTION:
  288.           oldVector.sv_handler = SIG_IGN;
  289.           break;
  290.  
  291.       default:
  292.           oldVector.sv_handler = (void (*)())oldAction.handler;
  293.           break;
  294.       }
  295.       (void) Compat_SpriteSigMaskToUnix(oldAction.sigHoldMask, 
  296.                                         &oldVector.sv_mask);
  297.           oldVector.sv_flags = 0;
  298.       status = Vm_CopyOut(sizeof(oldVector), (Address)&oldVector,
  299.                 (Address)oldVectorPtr);
  300.       if (status != SUCCESS) {
  301.           Mach_SetErrno(EFAULT);
  302.           return -1;
  303.       }
  304.       }
  305.       return 0;
  306. }
  307.  
  308.  
  309. /*
  310.  *----------------------------------------------------------------------
  311.  *
  312.  * Sig_SigblockStub --
  313.  *
  314.  *    Procedure to map from Unix sigblock system call to Sprite.
  315.  *
  316.  * Results:
  317.  *    Error code is returned upon error.  Otherwise SUCCESS is returned.
  318.  *
  319.  * Side effects:
  320.  *    Side effects associated with the system call.
  321.  *
  322.  *----------------------------------------------------------------------
  323.  */
  324. int
  325. Sig_SigblockStub(mask)
  326.     int mask;            /* additional bits to mask */
  327. {
  328.     int spriteMask = 0;        /* equivalent mask for Sprite */
  329.     int oldSpriteMask;        /* old mask, in Sprite terms */
  330.     ReturnStatus status;    /* generic result code */
  331.     register    Proc_ControlBlock    *procPtr = Proc_GetActualProc();
  332.     int oldMask;
  333.  
  334.     if (debugSigStubs) {
  335.     printf("Sig_SigblockStub(%x)\n", mask);
  336.     }
  337.     status = Compat_UnixSigMaskToSprite(mask, &spriteMask);
  338.     if (status == FAILURE) {
  339.     Mach_SetErrno(EINVAL);
  340.     return -1;
  341.     }
  342.     oldSpriteMask = procPtr->sigHoldMask;
  343.     if (status == FAILURE) {
  344.     Mach_SetErrno(EINVAL);
  345.     return -1;
  346.     }
  347.  
  348.     procPtr->sigHoldMask = (spriteMask | oldSpriteMask) & sigCanHoldMask;
  349.     procPtr->specialHandling = 1;
  350.     status = Compat_SpriteSigMaskToUnix(oldSpriteMask, &oldMask);
  351.     if (status == FAILURE) {
  352.     Mach_SetErrno(EINVAL);
  353.     return -1;
  354.     }
  355.     return oldMask;
  356. }
  357.  
  358.  
  359. /*
  360.  *----------------------------------------------------------------------
  361.  *
  362.  * Sig_SigsetmaskStub --
  363.  *
  364.  *    Procedure to map from Unix sigsetmask system call to Sprite.
  365.  *
  366.  * Results:
  367.  *    Error code is returned upon error.  Otherwise SUCCESS is returned.
  368.  *
  369.  * Side effects:
  370.  *    Side effects associated with the system call.
  371.  *
  372.  *----------------------------------------------------------------------
  373.  */
  374. int
  375. Sig_SigsetmaskStub(mask)
  376.     int mask;            /* new mask */
  377. {
  378.     int spriteMask = 0;        /* equivalent mask for Sprite */
  379.     int oldSpriteMask;        /* old mask, in Sprite terms */
  380.     ReturnStatus status;    /* generic result code */
  381.     int oldMask;
  382.     register    Proc_ControlBlock    *procPtr;
  383.  
  384.     if (debugSigStubs) {
  385.     printf("Sig_SigsetmaskStub(%x)\n");
  386.     }
  387.  
  388.     procPtr = Proc_GetActualProc();
  389.     status = Compat_UnixSigMaskToSprite(mask,&spriteMask);
  390.     if (status == FAILURE) {
  391.     Mach_SetErrno(EINVAL);
  392.     return -1;
  393.     }
  394.     procPtr->sigHoldMask = spriteMask & sigCanHoldMask;
  395.     oldSpriteMask = procPtr->sigHoldMask;
  396.     procPtr->sigHoldMask = spriteMask & sigCanHoldMask;
  397.     procPtr->specialHandling = 1;
  398.     status = Compat_SpriteSigMaskToUnix(oldSpriteMask, &oldMask);
  399.     if (status == FAILURE) {
  400.     Mach_SetErrno(EINVAL);
  401.     return -1;
  402.     }
  403.     return oldMask;
  404. }
  405.  
  406.  
  407. /*
  408.  *----------------------------------------------------------------------
  409.  *
  410.  * Sig_SigpauseStub --
  411.  *
  412.  *    Procedure to map from Unix sigpause system call to Sprite.
  413.  *
  414.  * Results:
  415.  *    Error code is returned upon error.  Otherwise SUCCESS is returned.
  416.  *
  417.  * Side effects:
  418.  *    Side effects associated with the system call.
  419.  *
  420.  *----------------------------------------------------------------------
  421.  */
  422. int
  423. Sig_SigpauseStub(mask)
  424.     int mask;            /* new mask */
  425. {
  426.     int spriteMask = 0;        /* equivalent mask for Sprite */
  427.     ReturnStatus status;    /* generic result code */
  428.  
  429.     if (debugSigStubs) {
  430.     printf("Sig_Sigpause\n");
  431.     }
  432.     status = Compat_UnixSigMaskToSprite(mask,&spriteMask);
  433.     if (status == FAILURE) {
  434.     Mach_SetErrno(EINVAL);
  435.     return -1;
  436.     }
  437.     status = Sig_Pause(spriteMask);
  438.     if (debugSigStubs) {
  439.     printf("Sig_Sigpause done\n");
  440.     }
  441.     Mach_SetErrno(EINTR);
  442.     if (status == GEN_ABORTED_BY_SIGNAL) {
  443.     Proc_GetCurrentProc()->unixProgress = PROC_PROGRESS_RESTART;
  444.     } else {
  445.     Proc_GetCurrentProc()->unixProgress = PROC_PROGRESS_MIG_RESTART;
  446.     }
  447.     return -1;
  448. }
  449.  
  450.  
  451. /*
  452.  *----------------------------------------------------------------------
  453.  *
  454.  * sigstack --
  455.  *
  456.  *    Procedure to fake the Unix sigstack system call.
  457.  *
  458.  * Results:
  459.  *    Error code is returned upon error.  Otherwise SUCCESS is returned.
  460.  *
  461.  * Side effects:
  462.  *    None.
  463.  *
  464.  *----------------------------------------------------------------------
  465.  */
  466. /*ARGSUSED*/
  467. int
  468. Sig_SigstackStub(ss, oss)
  469.     struct sigstack *ss, *oss;
  470. {
  471.     struct sigstack oldStack;
  472.  
  473.     if (debugSigStubs) {
  474.     printf("Sig_SigstackStub\n");
  475.     }
  476.     if (oss != NULL) {
  477.     oldStack.ss_sp = 0;
  478.     oldStack.ss_onstack = 0;
  479.     Vm_CopyOut(sizeof(struct sigstack), (Address)&oldStack,
  480.                       (Address)oss);
  481.     }
  482.     return 0;
  483. }
  484.